﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UIShell.OSGi;
using Pasys.PresentationCore;
using System.Windows.Forms;
using GeneratorLib.DB.Connectios;
using GeneratorLib.DB;
using GeneratorLib.DB.Schemas;
using Pasys.PresentationCore.DockShell;
using DBExplorer.Generators;
using GeneratorLib;
using System.Collections.ObjectModel;

namespace DBExplorer
{
    public class DBExplorerManager : IDBExplorerManager
    {
        //public
        public ConnectionInfos ConnectionInfos { get; private set; }


        //private
        private ICommandBusService commandBus;
        public DBExplorerManager()
        {

            ConnectionInfos = ConnectionInfos.Read();

            commandBus = BundleRuntime.Instance.GetFirstOrDefaultService<ICommandBusService>();
            //commandBus.SubscribeCommandEvent(CommandNames.NewSQL2008, NewSQL2008_Handler);
            //commandBus.SubscribeCommandEvent(CommandNames.NewMySQL, NewMySQL_Handler);
            commandBus.SubscribeCommandEvent(CommandNames.NewConnection, New_Handler);
            commandBus.SubscribeCommandEvent(CommandNames.EditConnection, EditConnection_Handler);
            commandBus.SubscribeCommandEvent(CommandNames.RemoveConnection, RemoveConnection_Handler);

            commandBus.SubscribeCommandEvent(CommandNames.ConnecteExplorer, ConnecteExplorer_Handler);

            //generator
            commandBus.SubscribeCommandEvent(CommandNames.DBExplorer_Generator_TableInfo, Generator_TableInfo_Handler);
            commandBus.SubscribeCommandEvent(CommandNames.DBExplorer_Generator_TemplateGenerator, Generator_TemplateGenerator_Handler);

            commandBus.SubscribeCommandEvent(CommandNames.Generator_Generator, Generator_Generator_Handler);
            commandBus.SubscribeCommandEvent(CommandNames.Generator_Save, Generator_Save_Handler);
            commandBus.SubscribeCommandEvent(CommandNames.Generator_Refresh, Generator_Refresh_Handler);

            //SetCommandStatus(CommandNames.ConnecteExplorer, true);
            //SetCommandStatus(CommandNames.ConnecteTableInfo, true);

        }

        void Generator_Generator_Handler(object sender, object e)
        {
            var layoutContaint = BundleRuntime.Instance.GetFirstOrDefaultService<ILayoutViewProxyContainer>();
            var workspace = layoutContaint.Workspace; // BundleRuntime.Instance.GetFirstOrDefaultService<IWorkspace>();
            if (workspace == null)
            {
                return;
            }
            var igen = workspace.ActiveSmartPart as GeneratorLib.IGenerator;
            if (igen == null)
            {
                return;
            }
            igen.Generate();
        }

        void Generator_Save_Handler(object sender, object e)
        {
            var layoutContaint = BundleRuntime.Instance.GetFirstOrDefaultService<ILayoutViewProxyContainer>();
            var workspace = layoutContaint.Workspace; // BundleRuntime.Instance.GetFirstOrDefaultService<IWorkspace>();
            if (workspace == null)
            {
                return;
            }
            var igen = workspace.ActiveSmartPart as GeneratorLib.IGenerator;
            if (igen == null)
            {
                return;
            }
            igen.Save();

        }

        void Generator_Refresh_Handler(object sender, object e)
        {
            var layoutContaint = BundleRuntime.Instance.GetFirstOrDefaultService<ILayoutViewProxyContainer>();
            var workspace = layoutContaint.Workspace; // BundleRuntime.Instance.GetFirstOrDefaultService<IWorkspace>();
            if (workspace == null)
            {
                return;
            }
            var igen = workspace.ActiveSmartPart as GeneratorLib.IGenerator;
            if (igen == null)
            {
                return;
            }
            igen.RefreshContent();
        }


        /*
        void NewSQL2008_Handler(object sender, object e)
        {

            SQLServer2008Connection info = new SQLServer2008Connection("SQLServer2008", "");

            DBConnecter frmCon = new DBConnecter()
            {
                IsMySQL = false
            };
            frmCon.ConnectionInfo = info;
            DialogResult res = frmCon.ShowDialog();
            if (res != DialogResult.OK) return;

            ConnectionInfos.AddItem(frmCon.ConnectionInfo);
            SetCurrentConnectionInfo(frmCon.ConnectionInfo, null);
            commandBus.PublicCommand(CommandNames.ConnectionCreated);

            //AddConnectionInfo(frmCon.ConnectionInfo);

        }

        void NewMySQL_Handler(object sender, object e)
        {
            MYSQLConnection info = new MYSQLConnection("MYSQL", "");

            DBConnecter frmCon = new DBConnecter()
            {
                IsMySQL = true
            };
            frmCon.ConnectionInfo = info;
            DialogResult res = frmCon.ShowDialog();
            if (res != DialogResult.OK) return;

            ConnectionInfos.AddItem(frmCon.ConnectionInfo);
            SetCurrentConnectionInfo(frmCon.ConnectionInfo, null);
            commandBus.PublicCommand(CommandNames.ConnectionCreated);
            //AddConnectionInfo(frmCon.ConnectionInfo);
        }
        */

        void New_Handler(object sender, object e)
        {
            var provideManager = BundleRuntime.Instance.GetFirstOrDefaultService<IDBProviderManager>();

            IDBProvider provider = null;
            ReadOnlyCollection<IDBProvider> types = provideManager.DBProviders;
            if (types.Count == 1)
            {
                provider = types[0];
            }
            else
            {
                provider =
                    new NewDBPrivoder().SelectDBProvider(provideManager.DBProviders) as IDBProvider;
            }
            if (provider == null)
            {
                return;
            }

            if (provider == null)
                return;

            var connection = provider.CreateNew();
            if (connection != null)
            {
                ConnectionInfos.AddItem(connection);
                SetCurrentConnectionInfo(connection, null);
                commandBus.PublicCommand(CommandNames.ConnectionCreated);
            }

        }


        void EditConnection_Handler(object sender, object e)
        {
            var conInfo = BundleRuntime.Instance.GetFirstOrDefaultService<IConnection>();
            if (conInfo == null) return;
            bool bl = false;

            if (conInfo.DBProvider != null)
            {
                bl = conInfo.DBProvider.EditConnection(conInfo);
            }
            else
            {
                var frmCon = new DBConnecter();
                frmCon.ConnectionInfo = conInfo;
                DialogResult res = frmCon.ShowDialog();
                bl = res == DialogResult.OK;
            }

            if (!bl) return;

            ConnectionInfos.Save();
            SetCurrentConnectionInfo(conInfo, null);
            commandBus.PublicCommand(CommandNames.ConnectionChanged);

        }

        void RemoveConnection_Handler(object sender, object e)
        {
            var conInfo = BundleRuntime.Instance.GetFirstOrDefaultService<IConnection>();
            if (conInfo != null)
            {
                var res = MessageBox.Show("will delete connection,continue?", Application.ProductName, MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
                if (res != DialogResult.OK)
                {
                    return;
                }

                ConnectionInfos.RemoveItem(conInfo);
                ConnectionInfos.Save();
                //trvConnections.Nodes.Remove(node);
                SetCurrentConnectionInfo(null, null);
                commandBus.PublicCommand(CommandNames.ConnectionRemoved);
            }
        }


        void ConnecteExplorer_Handler(object sender, object e)
        {
            showView(sender, new FrmExplorerProvider());
        }


        void Generator_TableInfo_Handler(object sender, object e)
        {
            var viewProvider = new TableFieldListProvider();
            showView(sender, viewProvider);
        }

        void Generator_TemplateGenerator_Handler(object sender, object e)
        {
            var viewProvider = new TemplateGeneratorProvider();
            showView(sender, viewProvider);
        }

        void showView(object sender, IPersistViewProvider viewProvider)
        {
            IShellLayoutViewProxy shellLayoutView = null;
            var find = sender as IFindOwnerForm;
            if (find != null)
            {
                var f = find.FindOwnerForm(); //as ILayoutViewProxyContainer;
                shellLayoutView = f.LayoutViewProxy;
            }

            if (shellLayoutView == null)
            {
                shellLayoutView = BundleRuntime.Instance.GetFirstOrDefaultService<IShellLayoutViewProxy>();
            }
            viewProvider.Onwer = shellLayoutView.Owner.FindForm();

            //var shellLayoutView = BundleRuntime.Instance.GetFirstOrDefaultService<IShellLayoutViewProxy>();
            if (shellLayoutView == null)
            {
                return;
            }

            shellLayoutView.Show(viewProvider);

            //if (viewProvider.ViewInfo == null)
            //{
            //    shellLayoutView.Show(viewProvider.View);
            //}
            //else
            //{
            //    shellLayoutView.Show(viewProvider.View, viewProvider.ViewInfo);
            //}


        }


        private void ActiveSmartPart(Control c)
        {
            var layoutContaint = BundleRuntime.Instance.GetFirstOrDefaultService<ILayoutViewProxyContainer>();
            var workspace = layoutContaint.Workspace; // BundleRuntime.Instance.GetFirstOrDefaultService<IWorkspace>();
            if (workspace == null)
            {
                return;
            }
            workspace.Activate(c);
        }

        private void SetTableInfoCommands(bool enabled, IGenerator gen)
        {
            commandBus.PublicToolbarStatus("tb_DBExplorer_TableInfo", enabled ? CommandStatus.Visible : CommandStatus.Hide);
            if (true)
            {
                bool bl1 = false, bl2 = false;
                if (gen != null)
                {
                    bl1 = gen.CanSave();
                    bl2 = gen.CanGenerate();
                }

                commandBus.PublicCommandStatus(CommandNames.Generator_Save, bl1 ? CommandStatus.Enabled : CommandStatus.Disabled);
                commandBus.PublicCommandStatus(CommandNames.Generator_Generator, bl2 ? CommandStatus.Enabled : CommandStatus.Disabled);

                //commandBus.PublicCommandStatus(CommandNames.TableInfo_AddRelationship, enabled ? CommandStatus.Visible : CommandStatus.Hide);
            }
        }




        public void Workspace_SmartPartActivated(object sender, WorkspaceEventArgs e)
        {
            var igen = e.SmartPart as IGenerator;
            if (igen != null)
            {
                SetTableInfoCommands(true, igen);
            }
            else
            {
                SetTableInfoCommands(false, igen);
            }
        }

        public void WorkspaceSmartPartClosing(object sender, WorkspaceCancelEventArgs e)
        {
            var igen = e.SmartPart as IGenerator;
            if (igen != null)
            {
                SetTableInfoCommands(false, igen);
            }
        }

        public void SetCurrentConnectionInfo(IConnection conInfo, ITableInfo tableInfo)
        {
            var c = BundleRuntime.Instance.GetFirstOrDefaultService<IConnection>();
            if (c != null)
            {
                BundleRuntime.Instance.RemoveService<IConnection>(c);
            }

            var t = BundleRuntime.Instance.GetFirstOrDefaultService<ITableInfo>();
            if (t != null)
            {
                BundleRuntime.Instance.RemoveService<ITableInfo>(t);
            }

            if (conInfo != null)
            {
                BundleRuntime.Instance.AddService<IConnection>(conInfo);
            }

            if (tableInfo != null)
            {
                BundleRuntime.Instance.AddService<ITableInfo>(tableInfo);
            }

            SetCommandStatus(CommandNames.DBExplorer_Generator_TableInfo, tableInfo != null);
            SetCommandStatus(CommandNames.DBExplorer_Generator_TemplateGenerator, tableInfo != null);

        }

        private void SetCommandStatus(string commandName, bool enabled)
        {
            commandBus.PublicCommandStatus(commandName, (enabled) ? CommandStatus.Enabled : CommandStatus.Disabled);
        }

    }

    /// <summary>
    /// Constants for command names.
    /// </summary>
    public class CommandNames
    {
        //commands
        public const string NewSQL2008 = "DBExplorer.NewSQL2008";
        public const string NewMySQL = "DBExplorer.NewMySQL";
        public const string NewConnection = "DBExplorer.NewConnection";
        public const string EditConnection = "DBExplorer.EditConnection";
        public const string RemoveConnection = "DBExplorer.RemoveConnection";
        public const string ConnecteConnection = "DBExplorer.ConnecteConnection";

        public const string ConnectionCreated = "DBExplorer.ConnectionCreated";
        public const string ConnectionChanged = "DBExplorer.ConnectionChanged";
        public const string ConnectionRemoved = "DBExplorer.ConnectionRemoved";

        //views
        public const string ConnecteExplorer = "DBExplorer.ConnecteExplorer";

        //generator
        public const string DBExplorer_Generator_TableInfo = "DBExplorer.Generator.TableInfo";
        public const string DBExplorer_Generator_TemplateGenerator = "DBExplorer.Generator.TemplateGenerator";

        //toolbar
        public const string Generator_Generator = "DBExplorer.Generator.Generator";
        public const string Generator_Save = "DBExplorer.Generator.Save";
        public const string Generator_Refresh = "DBExplorer.Generator.Refresh";



    }

    public class ExtensionPointNames
    {
        public const string ToolStrip = "DBExplorer.Explorer.Toolbar";
        public const string Explorer_ContextMenu = "DBExplorer.Explorer.ContextMenu";
        public const string Explorer_DBProvider = "DBExplorer.Explorer.DBProvider";
        public const string Explorer_DBTypeMapProvider = "DBExplorer.Explorer.DBTypeMapProvider";
    }
}
